#!/usr/bin/env python

import os

VERSION="1.0.4"

def find_library(library_names, lookup_paths):
    for directory in lookup_paths:
        for filename in library_names:
            libpam_path = os.path.join(directory, filename)
            if os.path.exists(libpam_path):
                return libpam_path
    return ''

def configure(conf):
    if conf.CHECK_BUNDLED_SYSTEM('pam_wrapper', minversion=VERSION, set_target=False):
        conf.DEFINE('USING_SYSTEM_PAM_WRAPPER', 1)
        libpam_wrapper_so_path = 'libpam_wrapper.so'
    else:
        # check HAVE_GCC_THREAD_LOCAL_STORAGE
        conf.CHECK_CODE('''
            __thread int tls;

            int main(void) {
                return 0;
            }
            ''',
            'HAVE_GCC_THREAD_LOCAL_STORAGE',
            addmain=False,
            msg='Checking for thread local storage')

        # check HAVE_DESTRUCTOR_ATTRIBUTE
        conf.CHECK_CODE('''
            void test_destructor_attribute(void) __attribute__ ((destructor));

            void test_destructor_attribute(void)
            {
                return;
            }

            int main(void) {
                return 0;
            }
            ''',
            'HAVE_DESTRUCTOR_ATTRIBUTE',
            addmain=False,
            msg='Checking for library destructor support')

        # check HAVE_FUNCTION_ATTRIBUTE_FORMAT
        conf.CHECK_CODE('''
            void log_fn(const char *format, ...) __attribute__ ((format (printf, 1, 2)));

            int main(void) {
                return 0;
            }
            ''',
            'HAVE_FUNCTION_ATTRIBUTE_FORMAT',
            addmain=False,
            msg='Checking for printf format validation support')

        conf.CHECK_HEADERS('security/pam_appl.h')
        conf.CHECK_HEADERS('security/pam_modules.h')
        conf.CHECK_HEADERS('security/pam_ext.h')

        conf.CHECK_FUNCS_IN('pam_vsyslog',
                            'pam',
                            checklibc=False,
                            headers='security/pam_ext.h')

        conf.CHECK_FUNCS_IN('pam_syslog',
                            'pam',
                            checklibc=False,
                            headers='security/pam_ext.h')

        conf.CHECK_C_PROTOTYPE('pam_vprompt',
                               'int pam_vprompt(const pam_handle_t *_pamh, int _style, char **_resp, const char *_fmt, va_list _ap)',
                               define='HAVE_PAM_VPROMPT_CONST', headers='stdio.h sys/types.h security/pam_appl.h security/pam_modules.h')

        conf.CHECK_C_PROTOTYPE('pam_prompt',
                               'int pam_prompt(const pam_handle_t *_pamh, int _style, char **_resp, const char *_fmt, ...)',
                               define='HAVE_PAM_PROMPT_CONST', headers='stdio.h sys/types.h security/pam_appl.h security/pam_modules.h')

        conf.CHECK_C_PROTOTYPE(
            'pam_strerror',
            'const char *pam_strerror(const pam_handle_t *pamh, int errnum)',
            define='HAVE_PAM_STRERROR_CONST',
            headers='''stdio.h sys/types.h security/pam_appl.h
                       security/pam_modules.h''')

        # Find the absolute path to libpam.so.0
        libpam_path = find_library(['libpam.so.0', 'libpam.so'], conf.env.STANDARD_LIBPATH)
        conf.DEFINE('PAM_LIBRARY', ('"%s"' % libpam_path ))

        # Create full path to pam_wrapper
        blddir = os.path.realpath(conf.blddir)
        libpam_wrapper_so_path = blddir + '/default/lib/pam_wrapper/libpam-wrapper.so'

    conf.DEFINE('LIBPAM_WRAPPER_SO_PATH', libpam_wrapper_so_path)
    conf.DEFINE('PAM_WRAPPER', 1)

def build(bld):
    if not bld.CONFIG_SET("USING_SYSTEM_PAM_WRAPPER"):
        # We need to do it this way or the library wont work.
        # Using private_library=True will add symbol version which
        # breaks preloading!
        bld.SAMBA_LIBRARY('pam_wrapper',
                          source='pam_wrapper.c',
                          deps='dl',
                          install=False,
                          realname='libpam-wrapper.so')

        # Can be used to write pam tests in python
        bld.SAMBA_PYTHON('pypamtest',
                         source='python/pypamtest.c libpamtest.c',
                         deps='dl pam',
                         install=False)
